﻿#pragma once

#include <learn/ais/ais_camera.h>
#include <learn/ais/ais_object.h>

namespace xi
{

namespace ais
{

class EXT_SYMBOL AIS_Context
{
  protected:
    struct Info
    {
        int64_t time;                        // 时间戳
        int width;                           // 窗口宽度
        int height;                          // 窗口高度
        AIS_Object *hang{nullptr};           // 悬停的物体
        AIS_Object *pressed{nullptr};        // 鼠标按下的物体
        std::vector<AIS_Object *> selected;  // 已经选中的所有物体
        std::shared_ptr<Camera> camera;      // 相机类
        std::shared_ptr<AIS_MouseMsg> mouse; // 鼠标消息
    };

    enum Action3d
    {
        None,
        Rotate,
        Scale,
        Translate
    };

    enum Dimension
    {
        Axis2d,
        Axis3d
    };

    float m_angleRate{0.25f};
    float m_scaleRate{2.0f};
    Action3d m_action{None};
    Dimension m_dimension{Axis3d};

    std::shared_ptr<Info> m_info;                       // 交互信息
    std::shared_ptr<RendererFactory> m_rendererFactory; // 渲染器工厂
    std::vector<std::shared_ptr<AIS_Object>> m_objects; // 所有物体

  public:
    AIS_Context(AIS_Context &&) = delete;

    /**
     * @brief 需要设置窗口大小
     *
     * @param[in] width
     * @param[in] height
     */
    AIS_Context(int width, int height);

    /**
     * @brief 移动鼠标事件
     *
     * @param[in] pos
     */
    void mouse_move_event(Vec2f pos);

    /**
     * @brief 按下鼠标事件
     *
     * @param[in] pos
     * @param[in] button
     */
    void mouse_press_event(Vec2f pos, AIS_MouseMsg::Button button);

    /**
     * @brief 释放鼠标事件
     *
     * @param[in] pos
     */
    void mouse_release_event(Vec2f pos);

    /**
     * @brief 滚轮事件
     *
     * @param[in] angleDelta
     */
    void mouse_wheel_event(Vec2f angleDelta);

    /**
     * @brief 键盘事件
     *
     * @param[in] key
     * @param[in] scancode
     * @param[in] action
     * @param[in] mods
     */
    void key_event(int key, int scancode, int action, int mods);

    /**
     * @brief 修改窗口大小事件
     *
     * @param[in] width
     * @param[in] height
     */
    void resize_event(int width, int height);

    /**
     * @brief 绘制事件
     *
     */
    void paint_event();

    /**
     * @brief 添加物体
     *
     * @param[in] object
     */
    void add_object(std::shared_ptr<AIS_Object> object);

    /**
     * @brief 获得渲染器工厂
     *
     * @return std::shared_ptr<RendererFactory>
     */
    std::shared_ptr<RendererFactory> renderer_factory() const noexcept;

    /**
     * @brief 用于访问交互信息
     *
     * @return Info*
     */
    Info *info() const noexcept;
};

} // namespace ais

} // namespace xi
